<template>
  <div class='songLyric'>
      <ul ref="ul"></ul>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { getLyric } from '@/api/music'

export default {
  name: 'songLyric',
  components: {},
  props: {
    changeCurrentTime: {
      required: true
    }
  },
  data () {
    return {
      timeArr: [],
      lyricArr: [],
      lyricIndex: -1
    }
  },
  computed: {
    ...mapState(['audio', 'playedSongId'])
  },
  watch: {
    playedSongId () {
      this.handleLyric()
    },
    // 手动拖动进度条时，歌词随改变后的时间产生变化
    changeCurrentTime () {
      this.updateLyricProgress(this.timeTosec(this.changeCurrentTime))
    }
  },
  created () {},
  mounted () {
    this.handleLyric()
  },
  destroyed () {
    // 当前页面销毁后，移除事件监听
    this.audio.removeEventListener('timeupdate', this.rollingLyric)
  },
  methods: {
    async handleLyric () {
      // 初始化歌词数组和时间数组
      this.lyricArr = []
      this.timeArr = []

      // 发送请求，获取歌词
      const { data } = await getLyric({
        id: this.playedSongId
      })

      // 提取歌曲内容，将时间与歌词分别放入各自的数组内
      const reg = /\[(\d{2}:\d{2})\.\d{2,3}\](.+)/g
      const ul = this.$refs.ul
      let tmp
      while ((tmp = reg.exec(data.lrc.lyric)) !== null) {
        this.timeArr.push(tmp[1])
        this.lyricArr.push(tmp[2])
      }
      this.updateLyricProgress(this.audio.currentTime * 60)

      // 判断是否获取到歌词
      // 无，提示‘无歌词’，不在进入后续的循环
      if (this.lyricArr.length === 0) {
        ul.style.top = 80 + 'px'
        ul.innerHTML = '<li>暂时无歌词</li>'
      } else {
        let str = ''
        // 循环歌词数组将歌词放入 li 标签，再将 li 标签作为 ul 的子元素
        this.lyricArr.forEach((item, index) => {
          str += `<li class="${index === 0 ? 'active' : ''}">${item}</li>`
        })
        ul.innerHTML = str

        // 绑定事件（监听播放器的时间变化）
        this.audio.addEventListener('timeupdate', this.rollingLyric)
      }
    },

    // 歌曲滚动
    rollingLyric () {
      const ul = this.$refs.ul
      // 歌词滚动
      if (this.lyricIndex !== -1) {
        ;[...ul.children].forEach(item => { item.className = '' })
        ul.children[this.lyricIndex].className = 'active'
        const lyricHeight = document.querySelectorAll('.active')[0].offsetTop
        ul.style.top = -lyricHeight + 80 + 'px'
      }
      // 格式化拿到的时间
      const { currentTime } = this.audio
      const minutes = parseInt(currentTime / 60)
      const seconds = parseInt(currentTime % 60)
      const timeStr = (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds)
      // 在时间数组中找到对应的索引
      this.lyricIndex = this.timeArr.findIndex(item => item === timeStr)
    },

    // 更新歌词进度
    updateLyricProgress (time) {
      const lyricIndex = this.timeArr.findIndex(ele => this.timeTosec(ele) > time)
      if (lyricIndex === -1) {
        this.lyricIndex = this.lyricArr.length - 1
      } else {
        this.lyricIndex = lyricIndex - 1
      }
    },

    // 分钟转秒数
    timeTosec: function (time) {
      var s = ''
      const hour = time.split(':')[0] || 0
      const min = time.split(':')[1] || 0
      const sec = time.split(':')[2] || 0
      s = Number(hour * 3600) + Number(min * 60) + Number(sec)
      return s
    }
  }
}
</script>
<style lang='less' scoped>
 .songLyric {
    font-size: 18px;
    text-align: center;
    width: 100%;
    height: 100%;
    margin: 10px 0;
    overflow: hidden;
    background-image: linear-gradient(to bottom, rgb(255, 255, 255), rgba(255, 255, 255, 0)10%, rgba(255, 255, 255, 0.1)90%, rgb(255, 255, 255));
    position: relative;
    /deep/ ul {
      transition: 0.6s;
      position: absolute;
      top: 80px;
      left: 0;
      bottom: 0;
      right: 0;
      z-index: -1;
      li {
        color: #aaa;
        margin-bottom: 18px;
        line-height: 20px;
        font-size: 14px;
      }
    }
    /deep/ .active {
      color: red;
    }
  }
</style>
